"""
日志配置模块
"""

import logging
import logging.handlers
import os
import sys
from pathlib import Path
from typing import Optional

from .config import settings


def setup_logging():
    """设置日志配置"""
    # 创建根日志器
    root_logger = logging.getLogger()
    root_logger.setLevel(getattr(logging, settings.LOG_LEVEL.upper()))
    
    # 清除现有处理器
    root_logger.handlers.clear()
    
    # 控制台处理器
    console_handler = logging.StreamHandler(sys.stdout)
    console_handler.setLevel(logging.INFO)
    
    # 控制台格式
    console_formatter = ColorFormatter()
    console_handler.setFormatter(console_formatter)
    
    root_logger.addHandler(console_handler)
    
    # 文件处理器
    if settings.LOG_FILE:
        # 确保日志目录存在
        log_dir = Path(settings.LOG_FILE).parent
        log_dir.mkdir(parents=True, exist_ok=True)
        
        # 根据轮转策略选择处理器
        if settings.LOG_ROTATION == "daily":
            file_handler = logging.handlers.TimedRotatingFileHandler(
                settings.LOG_FILE,
                when='midnight',
                interval=1,
                backupCount=settings.LOG_RETENTION,
                encoding='utf-8'
            )
        elif settings.LOG_ROTATION == "size":
            file_handler = logging.handlers.RotatingFileHandler(
                settings.LOG_FILE,
                maxBytes=10 * 1024 * 1024,  # 10MB
                backupCount=settings.LOG_RETENTION,
                encoding='utf-8'
            )
        else:
            file_handler = logging.FileHandler(
                settings.LOG_FILE,
                encoding='utf-8'
            )
        
        file_handler.setLevel(getattr(logging, settings.LOG_LEVEL.upper()))
        
        # 文件格式
        file_formatter = DetailedFormatter()
        file_handler.setFormatter(file_formatter)
        
        root_logger.addHandler(file_handler)
    
    # 设置第三方库日志级别
    logging.getLogger("uvicorn").setLevel(logging.INFO)
    logging.getLogger("uvicorn.access").setLevel(logging.WARNING)
    logging.getLogger("fastapi").setLevel(logging.INFO)
    logging.getLogger("sqlalchemy").setLevel(logging.WARNING)
    
    # 在开发模式下启用详细日志
    if settings.DEBUG:
        logging.getLogger("uvicorn").setLevel(logging.DEBUG)
        logging.getLogger("fastapi").setLevel(logging.DEBUG)
        logging.getLogger("sqlalchemy.engine").setLevel(logging.INFO)


class ColorFormatter(logging.Formatter):
    """彩色日志格式化器"""
    
    # 颜色代码
    COLORS = {
        'DEBUG': '\033[36m',    # 青色
        'INFO': '\033[32m',     # 绿色
        'WARNING': '\033[33m',  # 黄色
        'ERROR': '\033[31m',    # 红色
        'CRITICAL': '\033[35m', # 紫色
        'RESET': '\033[0m'      # 重置
    }
    
    def format(self, record):
        # 添加颜色
        level_color = self.COLORS.get(record.levelname, self.COLORS['RESET'])
        record.levelname = f"{level_color}{record.levelname}{self.COLORS['RESET']}"
        
        # 格式化消息
        log_format = (
            f"%(asctime)s - %(name)s - %(levelname)s - "
            f"%(filename)s:%(lineno)d - %(message)s"
        )
        
        formatter = logging.Formatter(log_format, datefmt='%Y-%m-%d %H:%M:%S')
        return formatter.format(record)


class DetailedFormatter(logging.Formatter):
    """详细日志格式化器"""
    
    def format(self, record):
        # 基本格式
        log_format = (
            "%(asctime)s - %(name)s - %(levelname)s - "
            "%(filename)s:%(lineno)d:%(funcName)s - %(message)s"
        )
        
        formatter = logging.Formatter(log_format, datefmt='%Y-%m-%d %H:%M:%S')
        formatted = formatter.format(record)
        
        # 添加异常信息（如果有）
        if record.exc_info:
            formatted += f"\n{self.formatException(record.exc_info)}"
        
        # 添加堆栈信息（如果有）
        if record.stack_info:
            formatted += f"\n{record.stack_info}"
        
        return formatted


class StructuredFormatter(logging.Formatter):
    """结构化日志格式化器（JSON格式）"""
    
    def format(self, record):
        import json
        from datetime import datetime
        
        log_entry = {
            'timestamp': datetime.utcnow().isoformat(),
            'level': record.levelname,
            'logger': record.name,
            'message': record.getMessage(),
            'module': record.module,
            'function': record.funcName,
            'line': record.lineno,
            'file': record.filename
        }
        
        # 添加异常信息
        if record.exc_info:
            log_entry['exception'] = self.formatException(record.exc_info)
        
        # 添加额外字段
        if hasattr(record, 'user_id'):
            log_entry['user_id'] = record.user_id
        
        if hasattr(record, 'request_id'):
            log_entry['request_id'] = record.request_id
        
        if hasattr(record, 'duration'):
            log_entry['duration'] = record.duration
        
        return json.dumps(log_entry, ensure_ascii=False)


def get_logger(name: str) -> logging.Logger:
    """获取日志器"""
    return logging.getLogger(name)


class RequestLogger:
    """请求日志器"""
    
    def __init__(self):
        self.logger = get_logger("request")
    
    def log_request(self, method: str, url: str, headers: dict = None, 
                   body: str = None, user_id: str = None):
        """记录请求"""
        self.logger.info(
            f"Request: {method} {url}",
            extra={
                'user_id': user_id,
                'method': method,
                'url': url,
                'headers': headers,
                'body_size': len(body) if body else 0
            }
        )
    
    def log_response(self, status_code: int, duration: float, 
                    response_size: int = 0, user_id: str = None):
        """记录响应"""
        log_level = logging.ERROR if status_code >= 500 else \
                    logging.WARNING if status_code >= 400 else logging.INFO
        
        self.logger.log(
            log_level,
            f"Response: {status_code} - {duration:.3f}s",
            extra={
                'user_id': user_id,
                'status_code': status_code,
                'duration': duration,
                'response_size': response_size
            }
        )


class ErrorLogger:
    """错误日志器"""
    
    def __init__(self):
        self.logger = get_logger("error")
    
    def log_exception(self, exception: Exception, context: dict = None):
        """记录异常"""
        import traceback
        
        error_info = {
            'exception_type': type(exception).__name__,
            'exception_message': str(exception),
            'traceback': traceback.format_exc(),
            'context': context or {}
        }
        
        self.logger.error(
            f"Exception: {type(exception).__name__}: {exception}",
            extra=error_info,
            exc_info=True
        )
    
    def log_error(self, message: str, context: dict = None):
        """记录错误"""
        self.logger.error(
            message,
            extra={'context': context or {}}
        )


class AuditLogger:
    """审计日志器"""
    
    def __init__(self):
        self.logger = get_logger("audit")
    
    def log_user_action(self, user_id: str, action: str, resource: str, 
                       details: dict = None):
        """记录用户操作"""
        self.logger.info(
            f"User Action: {user_id} {action} {resource}",
            extra={
                'user_id': user_id,
                'action': action,
                'resource': resource,
                'details': details or {}
            }
        )
    
    def log_system_event(self, event: str, details: dict = None):
        """记录系统事件"""
        self.logger.info(
            f"System Event: {event}",
            extra={
                'event': event,
                'details': details or {}
            }
        )


# 创建日志器实例
request_logger = RequestLogger()
error_logger = ErrorLogger()
audit_logger = AuditLogger()


def setup_sentry():
    """设置Sentry错误追踪"""
    if settings.SENTRY_DSN:
        try:
            import sentry_sdk
            from sentry_sdk.integrations.logging import LoggingIntegration
            from sentry_sdk.integrations.fastapi import FastApiIntegration
            from sentry_sdk.integrations.sqlalchemy import SqlalchemyIntegration
            
            # 配置Sentry集成
            logging_integration = LoggingIntegration(
                level=logging.INFO,
                event_level=logging.ERROR
            )
            
            sentry_sdk.init(
                dsn=settings.SENTRY_DSN,
                integrations=[
                    logging_integration,
                    FastApiIntegration(auto_enabling_integrations=False),
                    SqlalchemyIntegration(),
                ],
                environment="development" if settings.DEBUG else "production",
                release=settings.VERSION,
                traces_sample_rate=1.0 if settings.DEBUG else 0.1,
                send_default_pii=False
            )
            
            get_logger(__name__).info("Sentry initialized successfully")
            
        except Exception as e:
            get_logger(__name__).error(f"Failed to initialize Sentry: {e}")


class LogContext:
    """日志上下文管理器"""
    
    def __init__(self, logger: logging.Logger, **context):
        self.logger = logger
        self.context = context
        self.old_context = {}
    
    def __enter__(self):
        # 保存旧上下文
        if hasattr(self.logger, 'context'):
            self.old_context = self.logger.context.copy()
        else:
            self.logger.context = {}
        
        # 设置新上下文
        self.logger.context.update(self.context)
        return self.logger
    
    def __exit__(self, exc_type, exc_val, exc_tb):
        # 恢复旧上下文
        self.logger.context = self.old_context


def log_with_context(logger: logging.Logger, **context):
    """创建带上下文的日志器"""
    return LogContext(logger, **context)
